home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Tools / idle / ReplaceDialog.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  4.9 KB  |  169 lines

  1. import string
  2. import os
  3. import re
  4. import fnmatch
  5. from Tkinter import *
  6. import tkMessageBox
  7. import SearchEngine
  8. from SearchDialogBase import SearchDialogBase
  9.  
  10. def replace(text):
  11.     root = text._root()
  12.     engine = SearchEngine.get(root)
  13.     if not hasattr(engine, "_replacedialog"):
  14.         engine._replacedialog = ReplaceDialog(root, engine)
  15.     dialog = engine._replacedialog
  16.     dialog.open(text)
  17.  
  18. class ReplaceDialog(SearchDialogBase):
  19.  
  20.     title = "Replace Dialog"
  21.     icon = "Replace"
  22.  
  23.     def __init__(self, root, engine):
  24.         SearchDialogBase.__init__(self, root, engine)
  25.         self.replvar = StringVar(root)
  26.  
  27.     def open(self, text):
  28.         SearchDialogBase.open(self, text)
  29.         try:
  30.             first = text.index("sel.first")
  31.         except TclError:
  32.             first = None
  33.         try:
  34.             last = text.index("sel.last")
  35.         except TclError:
  36.             last = None
  37.         first = first or text.index("insert")
  38.         last = last or first
  39.         self.show_hit(first, last)
  40.         self.ok = 1
  41.  
  42.     def create_entries(self):
  43.         SearchDialogBase.create_entries(self)
  44.         self.replent = self.make_entry("Replace with:", self.replvar)
  45.  
  46.     def create_command_buttons(self):
  47.         SearchDialogBase.create_command_buttons(self)
  48.         self.make_button("Find", self.find_it)
  49.         self.make_button("Replace", self.replace_it)
  50.         self.make_button("Replace+Find", self.default_command, 1)
  51.         self.make_button("Replace All", self.replace_all)
  52.  
  53.     def find_it(self, event=None):
  54.         self.do_find(0)
  55.  
  56.     def replace_it(self, event=None):
  57.         if self.do_find(self.ok):
  58.             self.do_replace()
  59.  
  60.     def default_command(self, event=None):
  61.         if self.do_find(self.ok):
  62.             self.do_replace()
  63.             self.do_find(0)
  64.  
  65.     def replace_all(self, event=None):
  66.         prog = self.engine.getprog()
  67.         if not prog:
  68.             return
  69.         repl = self.replvar.get()
  70.         text = self.text
  71.         res = self.engine.search_text(text, prog)
  72.         if not res:
  73.             text.bell()
  74.             return
  75.         text.tag_remove("sel", "1.0", "end")
  76.         text.tag_remove("hit", "1.0", "end")
  77.         line = res[0]
  78.         col = res[1].start()
  79.         if self.engine.iswrap():
  80.             line = 1
  81.             col = 0
  82.         ok = 1
  83.         first = last = None
  84.         # XXX ought to replace circular instead of top-to-bottom when wrapping
  85.         while 1:
  86.             res = self.engine.search_forward(text, prog, line, col, 0, ok)
  87.             if not res:
  88.                 break
  89.             line, m = res
  90.             chars = text.get("%d.0" % line, "%d.0" % (line+1))
  91.             orig = m.group()
  92.             new = re.pcre_expand(m, repl)
  93.             i, j = m.span()
  94.             first = "%d.%d" % (line, i)
  95.             last = "%d.%d" % (line, j)
  96.             if new == orig:
  97.                 text.mark_set("insert", last)
  98.             else:
  99.                 text.mark_set("insert", first)
  100.                 if first != last:
  101.                     text.delete(first, last)
  102.                 if new:
  103.                     text.insert(first, new)
  104.             col = i + len(new)
  105.             ok = 0
  106.         if first and last:
  107.             self.show_hit(first, last)
  108.         self.close()
  109.  
  110.     def do_find(self, ok=0):
  111.         if not self.engine.getprog():
  112.             return 0
  113.         text = self.text
  114.         res = self.engine.search_text(text, None, ok)
  115.         if not res:
  116.             text.bell()
  117.             return 0
  118.         line, m = res
  119.         i, j = m.span()
  120.         first = "%d.%d" % (line, i)
  121.         last = "%d.%d" % (line, j)
  122.         self.show_hit(first, last)
  123.         self.ok = 1
  124.         return 1
  125.  
  126.     def do_replace(self):
  127.         prog = self.engine.getprog()
  128.         if not prog:
  129.             return 0
  130.         text = self.text
  131.         try:
  132.             first = pos = text.index("sel.first")
  133.             last = text.index("sel.last")
  134.         except TclError:
  135.             pos = None
  136.         if not pos:
  137.             first = last = pos = text.index("insert")
  138.         line, col = SearchEngine.get_line_col(pos)
  139.         chars = text.get("%d.0" % line, "%d.0" % (line+1))
  140.         m = prog.match(chars, col)
  141.         if not prog:
  142.             return 0
  143.         new = re.pcre_expand(m, self.replvar.get())
  144.         text.mark_set("insert", first)
  145.         if m.group():
  146.             text.delete(first, last)
  147.         if new:
  148.             text.insert(first, new)
  149.         self.show_hit(first, text.index("insert"))
  150.         self.ok = 0
  151.         return 1
  152.  
  153.     def show_hit(self, first, last):
  154.         text = self.text
  155.         text.mark_set("insert", first)
  156.         text.tag_remove("sel", "1.0", "end")
  157.         text.tag_add("sel", first, last)
  158.         text.tag_remove("hit", "1.0", "end")
  159.         if first == last:
  160.             text.tag_add("hit", first)
  161.         else:
  162.             text.tag_add("hit", first, last)
  163.         text.see("insert")
  164.         text.update_idletasks()
  165.  
  166.     def close(self, event=None):
  167.         SearchDialogBase.close(self, event)
  168.         self.text.tag_remove("hit", "1.0", "end")
  169.